namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
    /// <summary>
    /// 1. Start at Workplace homepage
    /// 2. Select Activities
    /// 3. Select New
    /// 4. Highlight Task and select OK
    /// 5. Enter "TaskSubject <date/time stamp>"
    /// 6. Save and Close
    /// </summary>

    public class CreateTask : CrmWebTest
    {
        public void CreateTask_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable userProps = new System.Collections.Hashtable();
            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                userProps.Add("role", e.WebTest.Context["UserRole"]);
                er.Props = userProps;
            }
            
            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];

            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            orgId = new Guid(user["organizationid"]);

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];            
        }
      
        public void CreateTask_PostWebTest(object sender, PostWebTestEventArgs e)
        {
			try
			{// Don't delete the entity till end of test run as it is deleted from crm.
                if (newTaskId != null)
                {
                    newTaskId = new Guid(newTaskId).ToString();
                    Guid g = EntityManager.Instance.GetOwnerGuid(new Guid(user[EntityIDNames.User]), new Guid(user["OrganizationId"]));
                    EntityManager.Instance.AddEntity(EntityNames.Tasks, g, new string[] { "OwningUser", "ActivityID", "EntityManagerOwningUser" }, new string[] { user["systemuserid"], newTaskId, g.ToString() });
                }
			}
            catch (System.FormatException fe)
            {
                System.Diagnostics.Trace.WriteLine("TaskId should never be set to anything other than Guid. This should not happen. " + fe.ToString());
            }
			finally
			{
				EntityManager.Instance.FreeEntity(user);
			}
        }

		private void NewTask_ValidateResponse(object sender, ValidationEventArgs e)
		{
			string ID = null;

			int idIdx = e.Response.BodyString.IndexOf(newIdMarker);
			ID = e.Response.BodyString.Substring(idIdx + (CreateTask.newIdMarker.Length), 36);
			try
			{
				ID = new Guid(ID).ToString();
			}
			catch (System.FormatException fe)
			{
				System.Diagnostics.Trace.WriteLine("Format exception: " + fe.ToString());
				e.IsValid = false;
				return;
			}
			e.IsValid = true;
		}

        public CreateTask()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            gridXml = GridXmlHelper.TaskPageViewRefresh(-1, TaskViewId, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(CreateTask_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(CreateTask_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
            Guid ownerid = new Guid(user["systemuserid"]);

			this.BeginTransaction("NavActivityHomepage");

            // Get the home page
            workplace_home_activities_aspx hp = new workplace_home_activities_aspx(user);
            yield return (hp);

			this.EndTransaction("NavActivityHomepage");

			this.BeginTransaction("CreateTask");

            activities_dlg_create_aspx createPage = new activities_dlg_create_aspx(user);
            yield return (createPage);

            activities_task_edit_aspx editPage = new activities_task_edit_aspx(user);
            yield return (editPage);

            referer = editPage.lastResponse.ResponseUri.AbsoluteUri;

            _forms_FormScript_js_aspx f = new _forms_FormScript_js_aspx(user);
            f.etc = 4212;
            f.FormType = "main";
            f.FormName = "crmForm";
            headerItem = new WebTestRequestHeader("referer", referer);
            f.Headers.Add(headerItem);
            yield return (f);

            activities_task_edit_aspx createFormPage = new activities_task_edit_aspx(user);
            createFormPage.crmFormSubmitXml = EntityXmlHelper.GetCreateTaskXml(ownerid, 8);

            rpcInfo = Utils.GenerateWRPCToken(activities_task_edit_aspx.url, user, tokenKey);
            createFormPage.CRMWRPCToken = rpcInfo.token;
            createFormPage.CRMWRPCTokenTimeStamp = rpcInfo.timeStamp;
            
            createFormPage.crmFormSubmitMode = 1;
            createFormPage.crmFormUserModified = true;
            createFormPage.crmFormSubmitObjectType = 4212;
            createFormPage.crmFormSubmitSecurity = 852023;
            createFormPage.crmFormSubmitOnline = 1;
			createFormPage.ValidateResponse += this.NewTask_ValidateResponse;
            yield return (createFormPage);

            //get the newly created Task id out of the post reply
            int idIdx = createFormPage.lastResponse.BodyString.IndexOf(newIdMarker);
            string tempNewTaskId = createFormPage.lastResponse.BodyString.Substring(idIdx + (CreateTask.newIdMarker.Length), 36);
			newTaskId = new Guid(tempNewTaskId).ToString();

            AppGridWebService.AppGridWebService ag = new AppGridWebService.AppGridWebService();
            CrmRequest wtr = null;

            try { ag.Refresh(gridXml); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                string urlPath = wtr.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtr.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtr.Headers.Add(headerItem);
                wtr.Method = "Post";
            }
            yield return (wtr);

            this.EndTransaction("CreateTask");        
        }
                
        private const string newIdMarker = @"separator + ""id=";
        private string gridXml;
        private CRMEntity user;        
        private string newTaskId;
        private string crmServer;
        private string tokenKey;
        private static string TaskViewId = "00000000-0000-0000-00AA-000010001899";
        private Guid orgId;

        private string referer;
        private WRPCInfo rpcInfo;
        private WebTestRequestHeader headerItem;
    }
}